package org.gp.core.service.impl;

import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.gp.core.entity.Bill;
import org.gp.core.entity.constant.Default;
import org.gp.core.entity.dto.ResponseDTO;
import org.gp.core.entity.enums.DTOCodeEnum;
import org.gp.core.entity.enums.HobbyEnum;
import org.gp.core.entity.result.*;
import org.gp.core.mapper.BillMapper;
import org.gp.core.service.IBillService;
import org.gp.core.utils.HobbyConvertUtil;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 账单表  服务实现类
 * </p>
 *
 * @author LuoLiang
 * @since 2017-02-27
 */
@Service
@Slf4j
public class BillServiceImpl extends ServiceImpl<BillMapper, Bill> implements IBillService {
    @Resource
    private BillMapper billMapper;
    @Resource
    private RedisTemplate redisTemplate;

    /**
     * 微信端获取用户饼状图
     *
     * @param userId
     * @return
     */
    @Override
    public ResponseDTO<List<PieData>> getPieChartData(Integer userId) {
        ResponseDTO<List<PieData>> dto = new ResponseDTO<>();

        try {
            List<ActivityCount> counts = billMapper.selectPieChart(userId);//查询出每个类型活动对应的数量
            List<PieData> pieDataList = new ArrayList<>(6);

            Map<String, PieData> pieDataMap = new HashMap<>();
            for (HobbyEnum hobbyEnum : HobbyEnum.values()) {//先遍历，设置默认值0，防止没有参加的活动类型不能统计
                pieDataMap.put(hobbyEnum.getDesc(), new PieData(hobbyEnum.getDesc(), 0));//生成Map k:活动类型   v:pieData对象
            }

            dto.setData(pieDataList);
            for (ActivityCount activityCount : counts) {//给上面生成的Map中value对象的活动数量赋值
                pieDataMap.get(activityCount.getActivityType()).setValue(activityCount.getCount());
            }

            for (Map.Entry<String, PieData> entry : pieDataMap.entrySet()) {
                pieDataList.add(entry.getValue());
            }

            dto.setCode(DTOCodeEnum.SUCCESS.getDesc());
        } catch (Exception e) {
            log.error("生成饼状图数据业务异常：", e);
            dto.setCode(DTOCodeEnum.FAIL.getDesc());
        }

        return dto;
    }

    @Override
    public ResponseDTO<BarData> getBarChartData(Integer userId) {
        ResponseDTO<BarData> dto = new ResponseDTO<>();
        dto.setData(new BarData());

        List<String> names = new ArrayList<>(6);
        List<Integer> values = new ArrayList<>(6);

        try {
            List<ActivityCost> activityCosts = billMapper.selectBarChart(userId);
            //从缓存中取
            Map<String, Integer> tempMap = (Map<String, Integer>) redisTemplate.opsForHash().entries(Default.ACTIVITYTYPEMAPKEY);
            //若没有，生成并放入缓存
            if (null == tempMap || tempMap.isEmpty()) {
                log.debug("柱状图缓存数据不存在，重新生成");
                tempMap = new HashMap<>(6);
                for (HobbyEnum hobbyEnum : HobbyEnum.values()) {
                    tempMap.put(hobbyEnum.getDesc().substring(0, 2), 0);
                }
                HashOperations hashOps = redisTemplate.opsForHash();
                hashOps.putAll(Default.ACTIVITYTYPEMAPKEY, tempMap);
            }

            for (ActivityCost cost : activityCosts) {
                names.add(cost.getActivityType().substring(0, 2));
                values.add(cost.getMoney());
            }

            for (Map.Entry<String, Integer> entry : tempMap.entrySet()) {
                if (!names.contains(entry.getKey())) {
                    names.add(entry.getKey());
                    values.add(entry.getValue());
                }
            }
            dto.getData().setNames(names.toArray(new String[names.size()]));
            dto.getData().setValues(values.toArray(new Integer[values.size()]));
            dto.setCode(DTOCodeEnum.SUCCESS.getDesc());
        } catch (Exception e) {
            log.error("生成柱状图数据业务异常：", e);
            dto.setCode(DTOCodeEnum.FAIL.getDesc());
        }

        return dto;
    }

    @Override
    public ResponseDTO<List<LineData>> getLineData(Integer userId) {
        ResponseDTO<List<LineData>> dto = new ResponseDTO<>();
        List<LineData> lineDataList = new ArrayList<>();

        Map<Integer, Integer> weekMap = new HashMap<>();
        for (int j = 1; j <= 7; j++) {
            weekMap.put(j, 0);
        }

        for (int i = 1; i <= 6; i++) {
            LineData lineData = new LineData();
            lineDataList.add(lineData);

            lineData.setName(HobbyEnum.HWLX.getDesc(HobbyConvertUtil.getHobbyKey(String.valueOf(i))));
            lineData.setType("line");
            lineData.setStack("总量");
            lineData.setAreaStyle(lineData.new AreaStyle());

            baseMapper.countActivityNumByWeek(userId, i)
                    .stream()
                    .forEach(activityWeekNum -> weekMap.put(activityWeekNum.getStartDate(), activityWeekNum.getCount()));
            List<Integer> dataList = new ArrayList<>();
            for (Map.Entry<Integer, Integer> entry : weekMap.entrySet()) {
                dataList.add(entry.getValue());
            }

            lineData.setData(dataList.toArray(new Integer[dataList.size()]));
        }

        dto.setData(lineDataList);

        return dto;
    }


}
